home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Field.java < prev    next >
Text File  |  1998-09-22  |  17KB  |  436 lines

  1. /*
  2.  * @(#)Field.java    1.10 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang.reflect;
  16.  
  17. /**
  18.  * A Field provides information about, and dynamic access to, a
  19.  * single field of a class or an interface.  The reflected field may
  20.  * be a class (static) field or an instance field.
  21.  *
  22.  * <p>A Field permits widening conversions to occur during a get or
  23.  * set access operation, but throws an IllegalArgumentException if a
  24.  * narrowing conversion would occur.
  25.  *
  26.  * @see Member
  27.  * @see java.lang.Class
  28.  * @see java.lang.Class#getFields()
  29.  * @see java.lang.Class#getField()
  30.  * @see java.lang.Class#getDeclaredFields()
  31.  * @see java.lang.Class#getDeclaredField()
  32.  *
  33.  * @author Nakul Saraiya
  34.  */
  35. public final
  36. class Field implements Member {
  37.  
  38.     private Class        clazz;
  39.     private int            slot;
  40.     private String        name;
  41.     private Class        type;
  42.  
  43.     /**
  44.      * Constructor.  Only the Java Virtual Machine may construct a Field.
  45.      */
  46.     private Field() {}
  47.  
  48.     /**
  49.      * Returns the Class object representing the class or interface
  50.      * that declares the field represented by this Field object.
  51.      */
  52.     public Class getDeclaringClass() {
  53.     return clazz;
  54.     }
  55.  
  56.     /**
  57.      * Returns the name of the field represented by this Field object.
  58.      */
  59.     public String getName() {
  60.     return name;
  61.     }
  62.  
  63.     /**
  64.      * Returns the Java language modifiers for the field represented
  65.      * by this Field object, as an integer. The Modifier class should
  66.      * be used to decode the modifiers.
  67.      *
  68.      * @see Modifier
  69.      */
  70.     public native int getModifiers();
  71.  
  72.     /**
  73.      * Returns a Class object that identifies the declared type for
  74.      * the field represented by this Field object.
  75.      */
  76.     public Class getType() {
  77.     return type;
  78.     }
  79.  
  80.     /**
  81.      * Compares this Field against the specified object.  Returns
  82.      * true if the objects are the same.  Two Fields are the same if
  83.      * they were declared by the same class and have the same name
  84.      * and type.
  85.      */
  86.     public boolean equals(Object obj) {
  87.     if (obj != null && obj instanceof Field) {
  88.         Field other = (Field)obj;
  89.         return (getDeclaringClass() == other.getDeclaringClass())
  90.         && (getName().equals(other.getName()))
  91.         && (getType() == other.getType());
  92.     }
  93.     return false;
  94.     }
  95.  
  96.     /**
  97.      * Returns a hashcode for this Field.  This is computed as the
  98.      * exclusive-or of the hashcodes for the underlying field's
  99.      * declaring class name and its name.
  100.      */
  101.     public int hashCode() {
  102.     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  103.     }
  104.  
  105.     /**
  106.      * Return a string describing this Field.  The format is
  107.      * the access modifiers for the field, if any, followed
  108.      * by the field type, followed by a space, followed by
  109.      * the fully-qualified name of the class declaring the field,
  110.      * followed by a period, followed by the name of the field.
  111.      * For example:
  112.      * <pre>
  113.      *    public static final int java.lang.Thread.MIN_PRIORITY
  114.      *    private int java.io.FileDescriptor.fd
  115.      * </pre>
  116.      *
  117.      * <p>The modifiers are placed in canonical order as specified by
  118.      * "The Java Language Specification".  This is <tt>public</tt>,
  119.      * <tt>protected</tt> or <tt>private</tt> first, and then other
  120.      * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
  121.      * <tt>transient</tt>, <tt>volatile</tt>.
  122.      */
  123.     public String toString() {
  124.     int mod = getModifiers();
  125.     return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
  126.         + getTypeName(getType()) + " "
  127.         + getTypeName(getDeclaringClass()) + "."
  128.         + getName());
  129.     }
  130.  
  131.     /**
  132.      * Returns the value of the field represented by this Field, on
  133.      * the specified object. The value is automatically wrapped in an
  134.      * object if it has a primitive type.
  135.      *
  136.      * <p>The underlying field's value is obtained as follows:
  137.      *
  138.      * <p>If the underlying field is a static field, the object argument
  139.      * is ignored; it may be null.
  140.      *
  141.      * <p>Otherwise, the underlying field is an instance field.  If the
  142.      * specified object argument is null, the method throws a
  143.      * NullPointerException. If the specified object is not an
  144.      * instance of the class or interface declaring the underlying
  145.      * field, the method throws an IllegalArgumentException.
  146.      *
  147.      * <p>If this Field object enforces Java language access control, and
  148.      * the underlying field is inaccessible, the method throws an
  149.      * IllegalAccessException.
  150.      *
  151.      * <p>Otherwise, the value is retrieved from the underlying instance
  152.      * or static field.  If the field has a primitive type, the value
  153.      * is wrapped in an object before being returned, otherwise it is
  154.      * returned as is.
  155.      *
  156.      * @exception IllegalAccessException    if the underlying constructor
  157.      *              is inaccessible.
  158.      * @exception IllegalArgumentException  if the specified object is not an
  159.      *              instance of the class or interface declaring the underlying
  160.      *              field.
  161.      * @exception NullPointerException      if the specified object is null.
  162.      */
  163.     public native Object get(Object obj)
  164.     throws IllegalArgumentException, IllegalAccessException;
  165.  
  166.     /**
  167.      * Get the value of a field as a boolean on specified object.
  168.      *
  169.      * @exception IllegalAccessException    if the underlying constructor
  170.      *              is inaccessible.
  171.      * @exception IllegalArgumentException  if the field value cannot be
  172.      *              converted to the return type by a widening conversion.
  173.      * @see       Field#get
  174.      */
  175.     public native boolean getBoolean(Object obj)
  176.     throws IllegalArgumentException, IllegalAccessException;
  177.  
  178.     /**
  179.      * Get the value of a field as a byte on specified object.
  180.      *
  181.      * @exception IllegalAccessException    if the underlying constructor
  182.      *              is inaccessible.
  183.      * @exception IllegalArgumentException  if the field value cannot be
  184.      *              converted to the return type by a widening conversion.
  185.      * @see       Field#get
  186.      */
  187.     public native byte getByte(Object obj)
  188.     throws IllegalArgumentException, IllegalAccessException;
  189.  
  190.     /**
  191.      * Get the value of a field as a char on specified object.
  192.      *
  193.      * @exception IllegalAccessException    if the underlying constructor
  194.      *              is inaccessible.
  195.      * @exception IllegalArgumentException  if the field value cannot be
  196.      *              converted to the return type by a widening conversion.
  197.      * @see       Field#get
  198.      */
  199.     public native char getChar(Object obj)
  200.     throws IllegalArgumentException, IllegalAccessException;
  201.  
  202.     /**
  203.      * Get the value of a field as a short on specified object.
  204.      *
  205.      * @exception IllegalAccessException    if the underlying constructor
  206.      *              is inaccessible.
  207.      * @exception IllegalArgumentException  if the field value cannot be
  208.      *              converted to the return type by a widening conversion.
  209.      * @see       Field#get
  210.      */
  211.     public native short getShort(Object obj)
  212.     throws IllegalArgumentException, IllegalAccessException;
  213.  
  214.     /**
  215.      * Get the value of a field as a int on specified object.
  216.      *
  217.      * @exception IllegalAccessException    if the underlying constructor
  218.      *              is inaccessible.
  219.      * @exception IllegalArgumentException  if the field value cannot be
  220.      *              converted to the return type by a widening conversion.
  221.      * @see       Field#get
  222.      */
  223.     public native int getInt(Object obj)
  224.     throws IllegalArgumentException, IllegalAccessException;
  225.  
  226.     /**
  227.      * Get the value of a field as a long on specified object.
  228.      *
  229.      * @exception IllegalAccessException    if the underlying constructor
  230.      *              is inaccessible.
  231.      * @exception IllegalArgumentException  if the field value cannot be
  232.      *              converted to the return type by a widening conversion.
  233.      * @see       Field#get
  234.      */
  235.     public native long getLong(Object obj)
  236.     throws IllegalArgumentException, IllegalAccessException;
  237.  
  238.     /**
  239.      * Get the value of a field as a float on specified object.
  240.      *
  241.      * @exception IllegalAccessException    if the underlying constructor
  242.      *              is inaccessible.
  243.      * @exception IllegalArgumentException  if the field value cannot be
  244.      *              converted to the return type by a widening conversion.
  245.      * @see       Field#get
  246.      */
  247.     public native float getFloat(Object obj)
  248.     throws IllegalArgumentException, IllegalAccessException;
  249.  
  250.     /**
  251.      * Get the value of a field as a double on specified object.
  252.      *
  253.      * @exception IllegalAccessException    if the underlying constructor
  254.      *              is inaccessible.
  255.      * @exception IllegalArgumentException  if the field value cannot be
  256.      *              converted to the return type by a widening conversion.
  257.      * @see       Field#get
  258.      */
  259.     public native double getDouble(Object obj)
  260.     throws IllegalArgumentException, IllegalAccessException;
  261.  
  262.     /**
  263.      * Sets the field represented by this Field object on the
  264.      * specified object argument to the specified new value. The new
  265.      * value is automatically unwrapped if the underlying field has a
  266.      * primitive type.
  267.      *
  268.      * <p>The operation proceeds as follows:
  269.      *
  270.      * <p>If the underlying field is static, the object argument is
  271.      * ignored; it may be null.
  272.      *
  273.      * <p>Otherwise the underlying field is an instance field.  If the
  274.      * specified object argument is null, the method throws a
  275.      * NullPointerException.  If the specified object argument is not
  276.      * an instance of the class or interface declaring the underlying
  277.      * field, the method throws an IllegalArgumentException.
  278.      *
  279.      * <p>If this Field object enforces Java language access control, and
  280.      * the underlying field is inaccessible, the method throws an
  281.      * IllegalAccessException.
  282.      *
  283.      * <p>If the underlying field is final, the method throws an
  284.      * IllegalAccessException.
  285.      *
  286.      * <p>If the underlying field is of a primitive type, an unwrapping
  287.      * conversion is attempted to convert the new value to a value of
  288.      * a primitive type.  If this attempt fails, the method throws an
  289.      * IllegalArgumentException.
  290.      *
  291.      * <p>If, after possible unwrapping, the new value cannot be
  292.      * converted to the type of the underlying field by an identity or
  293.      * widening conversion, the method throws an
  294.      * IllegalArgumentException.
  295.      *
  296.      * <p>The field is set to the possibly unwrapped and widened new value.
  297.      *
  298.      * @exception IllegalAccessException    if the underlying constructor
  299.      *              is inaccessible.
  300.      * @exception IllegalArgumentException  if the specified object is not an
  301.      *              instance of the class or interface declaring the underlying
  302.      *              field, or if an unwrapping conversion fails.
  303.      * @exception NullPointerException      if the specified object is null.
  304.      */
  305.     public native void set(Object obj, Object value)
  306.     throws IllegalArgumentException, IllegalAccessException;
  307.  
  308.     /**
  309.      * Set the value of a field as a boolean on specified object.
  310.      *
  311.      * @exception IllegalAccessException    if the underlying constructor
  312.      *              is inaccessible.
  313.      * @exception IllegalArgumentException  if the specified object is not an
  314.      *              instance of the class or interface declaring the underlying
  315.      *              field, or if an unwrapping conversion fails.
  316.      * @see       Field#set
  317.      */
  318.     public native void setBoolean(Object obj, boolean z)
  319.     throws IllegalArgumentException, IllegalAccessException;
  320.  
  321.     /**
  322.      * Set the value of a field as a byte on specified object.
  323.      *
  324.      * @exception IllegalAccessException    if the underlying constructor
  325.      *              is inaccessible.
  326.      * @exception IllegalArgumentException  if the specified object is not an
  327.      *              instance of the class or interface declaring the underlying
  328.      *              field, or if an unwrapping conversion fails.
  329.      * @see       Field#set
  330.      */
  331.     public native void setByte(Object obj, byte b)
  332.     throws IllegalArgumentException, IllegalAccessException;
  333.  
  334.     /**
  335.      * Set the value of a field as a char on specified object.
  336.      *
  337.      * @exception IllegalAccessException    if the underlying constructor
  338.      *              is inaccessible.
  339.      * @exception IllegalArgumentException  if the specified object is not an
  340.      *              instance of the class or interface declaring the underlying
  341.      *              field, or if an unwrapping conversion fails.
  342.      * @see       Field#set
  343.      */
  344.     public native void setChar(Object obj, char c)
  345.     throws IllegalArgumentException, IllegalAccessException;
  346.  
  347.     /**
  348.      * Set the value of a field as a short on specified object.
  349.      *
  350.      * @exception IllegalAccessException    if the underlying constructor
  351.      *              is inaccessible.
  352.      * @exception IllegalArgumentException  if the specified object is not an
  353.      *              instance of the class or interface declaring the underlying
  354.      *              field, or if an unwrapping conversion fails.
  355.      * @see       Field#set
  356.      */
  357.     public native void setShort(Object obj, short s)
  358.     throws IllegalArgumentException, IllegalAccessException;
  359.  
  360.     /**
  361.      * Set the value of a field as an int on specified object.
  362.      *
  363.      * @exception IllegalAccessException    if the underlying constructor
  364.      *              is inaccessible.
  365.      * @exception IllegalArgumentException  if the specified object is not an
  366.      *              instance of the class or interface declaring the underlying
  367.      *              field, or if an unwrapping conversion fails.
  368.      * @see       Field#set
  369.      */
  370.     public native void setInt(Object obj, int i)
  371.     throws IllegalArgumentException, IllegalAccessException;
  372.  
  373.     /**
  374.      * Set the value of a field as a long on specified object.
  375.      *
  376.      * @exception IllegalAccessException    if the underlying constructor
  377.      *              is inaccessible.
  378.      * @exception IllegalArgumentException  if the specified object is not an
  379.      *              instance of the class or interface declaring the underlying
  380.      *              field, or if an unwrapping conversion fails.
  381.      * @see       Field#set
  382.      */
  383.     public native void setLong(Object obj, long l)
  384.     throws IllegalArgumentException, IllegalAccessException;
  385.  
  386.     /**
  387.      * Set the value of a field as a float on specified object.
  388.      *
  389.      * @exception IllegalAccessException    if the underlying constructor
  390.      *              is inaccessible.
  391.      * @exception IllegalArgumentException  if the specified object is not an
  392.      *              instance of the class or interface declaring the underlying
  393.      *              field, or if an unwrapping conversion fails.
  394.      * @see       Field#set
  395.      */
  396.     public native void setFloat(Object obj, float f)
  397.     throws IllegalArgumentException, IllegalAccessException;
  398.  
  399.     /**
  400.      * Set the value of a field as a double on specified object.
  401.      *
  402.      * @exception IllegalAccessException    if the underlying constructor
  403.      *              is inaccessible.
  404.      * @exception IllegalArgumentException  if the specified object is not an
  405.      *              instance of the class or interface declaring the underlying
  406.      *              field, or if an unwrapping conversion fails.
  407.      * @see       Field#set
  408.      */
  409.     public native void setDouble(Object obj, double d)
  410.     throws IllegalArgumentException, IllegalAccessException;
  411.  
  412.     /*
  413.      * Utility routine to paper over array type names
  414.      */
  415.     static String getTypeName(Class type) {
  416.     if (type.isArray()) {
  417.         try {
  418.         Class cl = type;
  419.         int dimensions = 0;
  420.         while (cl.isArray()) {
  421.             dimensions++;
  422.             cl = cl.getComponentType();
  423.         }
  424.         StringBuffer sb = new StringBuffer();
  425.         sb.append(cl.getName());
  426.         for (int i = 0; i < dimensions; i++) {
  427.             sb.append("[]");
  428.         }
  429.         return sb.toString();
  430.         } catch (Throwable e) { /*FALLTHRU*/ }
  431.     }
  432.     return type.getName();
  433.     }
  434.  
  435. }
  436.